package org.seamon.management.controller;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.seamon.management.pojo.dto.ResetPwdDto;
import org.seamon.management.pojo.dto.UserListDto;
import org.seamon.management.pojo.dto.UserRoleInsertDto;
import org.seamon.management.pojo.dto.UserUpdateDto;
import org.seamon.management.service.UserRoleService;
import org.seamon.management.service.UserService;
import org.seamon.management.util.Result;
import org.seamon.management.util.aspect.DataPermission;
import org.seamon.management.util.aspect.Limit;
import org.seamon.management.util.aspect.Log;
import org.seamon.management.util.enums.BusinessTypeEnum;
import org.seamon.management.util.exception.BusinessException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/api/user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private UserRoleService userRoleService;

    @PreAuthorize("hasAuthority('user:list')")
    @Log(title = "获取用户列表", businessType = BusinessTypeEnum.LIST)
    @PostMapping("/list")
    public Result<?> list(@RequestBody UserListDto dto) {
        log.info("获取用户列表, 筛选条件：部门id：{}，启用状态：{}", dto.getDeptId(), dto.getStatus());
        log.info("第 {} 页，每页 {} 条", dto.getCurrent(), dto.getSize());
        return Result.success(userService.listUser(dto));
    }

    @PreAuthorize("hasAuthority('user:detail')")
    @Log(title = "获取用户详情", businessType = BusinessTypeEnum.DETAIL)
    @GetMapping("/{id}")
    public Result<?> getById(@PathVariable Long id) {
        log.info("获取用户信息，id：{}", id);
        return Result.success(userService.getUserById(id));
    }

    @Limit(key = "user_update", permitsPerSecond = 10, timeout = 1, timeunit = TimeUnit.SECONDS)
    @PreAuthorize("hasAuthority('user:edit')")
    @DataPermission(userIdSpel = "#dto.id", selfOnly = true)
    @Log(title = "更新用户信息", businessType = BusinessTypeEnum.UPDATE)
    @PutMapping
    public Result<?> update(@RequestBody @Valid UserUpdateDto dto) {
        log.info("更新用户信息：{}", dto);
        userService.updateUser(dto);
        return Result.success();
    }

    @Limit(key = "user_delete", permitsPerSecond = 10, timeout = 1, timeunit = TimeUnit.SECONDS)
    @PreAuthorize("hasAuthority('user:delete')")
    @Log(title = "删除用户", businessType = BusinessTypeEnum.DELETE)
    @DeleteMapping("/{id}")
    public Result<?> delete(@PathVariable Long id) {
        log.info("删除用户, id: {}", id);
        userService.removeUserById(id);
        return Result.success();
    }

    @Limit(key = "user_resetPwd", permitsPerSecond = 10, timeout = 1, timeunit = TimeUnit.SECONDS)
    @PreAuthorize("hasAuthority('user:resetPwd')")
    @DataPermission(userIdSpel = "#dto.id", selfOnly = true)
    @Log(title = "重置密码", businessType = BusinessTypeEnum.UPDATE)
    @PutMapping("/reset-pwd")
    public Result<?> resetPwd(@RequestBody @Valid ResetPwdDto dto) throws BusinessException {
        log.info("重置用户密码：{}", dto.getId());
        userService.resetPwd(dto);
        return Result.success();
    }

    @PreAuthorize("hasAuthority('user:role')")
    @Log(title = "获取用户角色列表", businessType = BusinessTypeEnum.LIST)
    @GetMapping("/role/{userId}")
    public Result<?> getRole(@PathVariable Long userId) {
        log.info("获取用户角色列表：{}", userId);
        return Result.success(userRoleService.getRole(userId));
    }

    @Limit(key = "user_saveRole", permitsPerSecond = 10, timeout = 1, timeunit = TimeUnit.SECONDS)
    @PreAuthorize("hasAuthority('user:assignRole')")
    @Log(title = "保存用户角色关系", businessType = BusinessTypeEnum.UPDATE)
    @PostMapping("/role")
    public Result<?> saveRole(@RequestBody @Valid UserRoleInsertDto dto) {
        log.info("保存用户角色关系：{}", dto);
        userRoleService.saveRole(dto);
        return Result.success();
    }

    @Limit(key = "user_deleteRole", permitsPerSecond = 10, timeout = 1, timeunit = TimeUnit.SECONDS)
    @PreAuthorize("hasAuthority('user:deleteRole')")
    @Log(title = "删除用户角色关系", businessType = BusinessTypeEnum.DELETE)
    @DeleteMapping("/role/{userRoleId}")
    public Result<?> deleteRole(@PathVariable Long userRoleId) {
        log.info("删除用户角色关系：{}", userRoleId);
        userRoleService.removeUserRoleById(userRoleId);
        return Result.success();
    }
}
